package com.seawave.sdkclientjdk8.util;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class SimpleHttpsClient {

	private static Map<Integer, Integer> registerPortList = new HashMap<Integer, Integer>();
	final public static String FORM_DATE = "multipart/form-data";
	final public static String FORM = "application/x-www-form-urlencoded;charset=UTF-8";

	/**
	 * doPost/Proxy
	 *
	 * @param url
	 * @param
	 * @return
	 * @throws MalformedURLException
	 */
	public static String postRequest(String url, Map<String, String> params ,String charSet ,String contentType) {
		return postRequest(url, null, params, charSet, null, null, contentType);
	}

	public static String postRequest(String url, Map<String, String> params ,String charSet) {
		return postRequest(url, null, params, charSet, null, null, "application/x-www-form-urlencoded;charset="+charSet);
	}

	public static String postRequest(String url, String entry ,String charSet ,String contentType) {
		return postRequest(url, entry, null, charSet, null, null, contentType);
	}

	public static String postRequest(String url, String entry ,String charSet) {
		return postRequest(url, entry, null, charSet, null, null, "text/html;charset="+charSet);
	}

	public static String postRequest(String url, Map<String, String> params , String charSet, String proxyHost, String proxyPort, String contentType){
		return postRequest(url, null, params, charSet, proxyHost, proxyPort, contentType);
	}

	public static String postRequest(String url, Map<String, String> params , String charSet, String proxyHost, String proxyPort){
		return postRequest(url, null, params, charSet, proxyHost, proxyPort, "application/x-www-form-urlencoded;charset="+charSet);
	}

	public static String postRequest(String url, String entry ,String charSet, String proxyHost, String proxyPort, String contentType) {
		return postRequest(url, entry, null, charSet, proxyHost, proxyPort, contentType);
	}

	public static String postRequest(String url, String entry ,String charSet, String proxyHost, String proxyPort) {
		return postRequest(url, entry, null, charSet, proxyHost, proxyPort, "text/html;charset="+charSet);
	}

	public static String postRequest(String url, String entry, Map<String, String> params , String charSet, String proxyHost, String proxyPort,String contentType) {
		Integer port = getPort(url);
		HttpClient client = new HttpClient();
		if (StringUtils.isNotBlank(proxyHost) && StringUtils.isNotBlank(proxyPort)) {
			client.getHostConfiguration().setProxy(proxyHost, Integer.parseInt(proxyPort));
		}
		PostMethod postMethod = new PostMethod(url);
		postMethod.setRequestHeader("Connection", "close");
		if(StringUtils.isNotBlank(contentType)) {
			postMethod.addRequestHeader("Content-Type", contentType);
		}
		if (StringUtils.isNotBlank(entry)) {
			postMethod.setRequestEntity(new StringRequestEntity(entry));
			//postMethod.setRequestBody(entry);
		}else{
			if(params!=null&&params.size()>0){
				NameValuePair[] data = createNameValuePair(params);
				postMethod.setRequestBody(data);
			}
		}
		postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,charSet);
		client.getParams().setSoTimeout(30000);
		String responseBody = null;
		try {
			int status = client.executeMethod(postMethod);
			InputStream is = postMethod.getResponseBodyAsStream();
			responseBody = IOUtils.toString(is, charSet);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			postMethod.releaseConnection();
		}
		return responseBody;
	}

	/**
	 * doGet/Proxy
	 *
	 * @param url
	 * @param params
	 * @return
	 */
	public static String getRequest(String url, Map<String, String> params ,String charSet) {
		return getRequest(url, params, charSet, null, null);
	}

	public static String getRequest(String url, Map<String, String> params , String charSet, String proxyHost, String proxyPort) {
		Integer port = getPort(url);
		if(params!=null&&params.size()>0){
			url = appendUrlParam(url, params);
		}
		HttpClient httpclient = new HttpClient();
		if (StringUtils.isNotBlank(proxyHost) && StringUtils.isNotBlank(proxyPort)) {
			httpclient.getHostConfiguration().setProxy(proxyHost, Integer.parseInt(proxyPort));
		}
		GetMethod httpget = new GetMethod(url);
		httpclient.getParams().setSoTimeout(10000);
		String responseBody = null;
		try {
			int status = httpclient.executeMethod(httpget);
			InputStream is = httpget.getResponseBodyAsStream();
			responseBody = IOUtils.toString(is, charSet);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			httpget.releaseConnection();
		}
		return responseBody;
	}

	private static Integer getPort(String uri) {
		try {
			URL url = new URL(uri);
			int port = url.getPort();
			if (port == -1) {
				if (uri.indexOf("https://") == 0) {
					port = 443;
				} else {
					port = 80;
				}
			}
			return port;
		} catch (MalformedURLException e) {
			throw new RuntimeException(e);
		}
	}

	private static NameValuePair[] createNameValuePair(Map<String, String> params) {
		NameValuePair[] pairs = new NameValuePair[params.size()];
		int index = 0;
		for (String key : params.keySet()) {
			pairs[index++] = new NameValuePair(key, params.get(key));
		}
		return pairs;
	}

	private static String appendUrlParam(String url, Map<String, String> params) {
		String result = "";
		if (url.contains("?") && url.contains("=")) {
			result = url + "&";
		} else {
			result = url + "?";
		}
		for (String key : params.keySet()) {
			result = result + key + "=" + params.get(key) + "&";
		}
		if (result.charAt(result.length() - 1) == '&') {
			result = result.substring(0, result.length() - 1);
		}
		return result;
	}

}
